package com.smart.thrift.model.server;

import com.smart.thrift.model.common.ThriftServerProperties;
import com.smart.thrift.model.wrapper.ThriftServiceWrapper;
import org.apache.thrift.transport.TTransportException;

import java.io.IOException;
import java.util.List;
import java.util.Objects;

public interface ServerBuilder {

    ServerBuilder build();

    IThriftServer buildThriftServer(ThriftServerProperties properties,
                              List<ThriftServiceWrapper> serviceWrappers)
            throws TTransportException, IOException;


    class THsHaServerSingletonBuilder implements ServerBuilder {
        private static THsHaServerSingletonBuilder serverBuilder;
        private ThriftHsHaServer.Args args;

        private THsHaServerSingletonBuilder() {}

        public static THsHaServerSingletonBuilder getInstance() {
            if (Objects.isNull(serverBuilder)) {
                serverBuilder = new THsHaServerSingletonBuilder();
            }
            return serverBuilder;
        }

        @Override
        public ServerBuilder build() {
            return getInstance();
        }

        @Override
        public IThriftServer buildThriftServer(ThriftServerProperties properties, List<ThriftServiceWrapper> serviceWrappers) throws TTransportException, IOException {
            serverBuilder = getInstance();
            serverBuilder.args = new ThriftHsHaServer.Args(serviceWrappers, properties);
            return new ThriftHsHaServer(args);
        }
    }

    class TNonBlockingServerSingletonBuilder implements ServerBuilder {
        private static TNonBlockingServerSingletonBuilder serverBuilder;
        private ThriftNonBlockingServer.Args args;

        private TNonBlockingServerSingletonBuilder() {}

        public static TNonBlockingServerSingletonBuilder getInstance() {
            if (Objects.isNull(serverBuilder)) {
                serverBuilder = new TNonBlockingServerSingletonBuilder();
            }
            return serverBuilder;
        }


        @Override
        public ServerBuilder build() {
            return getInstance();
        }

        @Override
        public IThriftServer buildThriftServer(ThriftServerProperties properties, List<ThriftServiceWrapper> serviceWrappers) throws TTransportException, IOException {
            serverBuilder = getInstance();
            serverBuilder.args = new ThriftNonBlockingServer.Args(serviceWrappers, properties);
            return new ThriftNonBlockingServer(args);
        }
    }

    class TSimpleServerSingletonBuilder implements ServerBuilder {
        private static TSimpleServerSingletonBuilder serverBuilder;
        private ThriftSimpleServer.Args args;

        private TSimpleServerSingletonBuilder() {}

        public static TSimpleServerSingletonBuilder getInstance() {
            if (Objects.isNull(serverBuilder)) {
                serverBuilder = new TSimpleServerSingletonBuilder();
            }
            return serverBuilder;
        }


        @Override
        public ServerBuilder build() {
            return getInstance();
        }

        @Override
        public IThriftServer buildThriftServer(ThriftServerProperties properties, List<ThriftServiceWrapper> serviceWrappers) throws TTransportException, IOException {
            serverBuilder = getInstance();
            serverBuilder.args = new ThriftSimpleServer.Args(serviceWrappers, properties);
            return new ThriftSimpleServer(args);
        }
    }

    class TThreadedSelectorServerSingletonBuilder implements ServerBuilder {
        private static TThreadedSelectorServerSingletonBuilder serverBuilder;
        private ThriftThreadedSelectorServer.Args args;

        private TThreadedSelectorServerSingletonBuilder() {}

        public static TThreadedSelectorServerSingletonBuilder getInstance() {
            if (Objects.isNull(serverBuilder)) {
                serverBuilder = new TThreadedSelectorServerSingletonBuilder();
            }
            return serverBuilder;
        }


        @Override
        public ServerBuilder build() {
            return getInstance();
        }

        @Override
        public IThriftServer buildThriftServer(ThriftServerProperties properties, List<ThriftServiceWrapper> serviceWrappers) throws TTransportException, IOException {
            serverBuilder = getInstance();
            serverBuilder.args = new ThriftThreadedSelectorServer.Args(serviceWrappers, properties);
            return new ThriftThreadedSelectorServer(args);
        }
    }

    class TThreadPoolServerSingletonBuilder implements ServerBuilder {
        private static TThreadPoolServerSingletonBuilder serverBuilder;
        private ThriftThreadPoolServer.Args args;

        private TThreadPoolServerSingletonBuilder() {}

        public static TThreadPoolServerSingletonBuilder getInstance() {
            if (Objects.isNull(serverBuilder)) {
                serverBuilder = new TThreadPoolServerSingletonBuilder();
            }
            return serverBuilder;
        }


        @Override
        public ServerBuilder build() {
            return getInstance();
        }

        @Override
        public IThriftServer buildThriftServer(ThriftServerProperties properties, List<ThriftServiceWrapper> serviceWrappers) throws TTransportException, IOException {
            serverBuilder = getInstance();
            serverBuilder.args = new ThriftThreadPoolServer.Args(serviceWrappers, properties);
            return new ThriftThreadPoolServer(args);
        }
    }
}
